package com.woody.aggregate.application.service.settings.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Preconditions;
import com.woody.aggregate.domain.settings.SysCategoryConfigManager;
import com.woody.aggregate.domain.msgsendrule.MsgSendRuleManager;
import com.woody.aggregate.settings.req.SaveSysCategoryConfigReq;
import com.woody.aggregate.settings.vo.SysCategoryConfigDetailVo;
import com.woody.aggregate.infrastructure.settings.entity.SysCategoryConfig;
import com.woody.aggregate.application.service.settings.ISysCategoryConfigService;
import com.woody.base.exception.BaseException;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 分类配置 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-03-20
 */
@Service
public class SysCategoryConfigServiceImpl implements ISysCategoryConfigService {

    @Autowired
    private SysCategoryConfigManager categoryConfigManager;

    @Autowired
    private MsgSendRuleManager msgSendRuleManager;

    /**
     * 根据业务类型查询分类列表
     * <br />
     *
     * @param bizType 业务类型，不能为null
     * @return
     */
    @Override
    public List<SysCategoryConfigDetailVo> listCategoryConfigByType(Integer bizType) {
        Preconditions.checkArgument(bizType != null, "业务类型不能为空");

        // 查询分类列表
        LambdaQueryWrapper<SysCategoryConfig> configWrapper = new LambdaQueryWrapper<>();
        configWrapper.eq(SysCategoryConfig::getBizType, bizType);
        List<SysCategoryConfig> sysCategoryConfigs = categoryConfigManager.list(configWrapper);

        if (CollectionUtils.isEmpty(sysCategoryConfigs)) {
            return Collections.emptyList();
        }

        // 查询有规则的分类
        List<Integer> categoryIds = sysCategoryConfigs.stream().map(SysCategoryConfig::getId).collect(Collectors.toList());
        List<Integer> usedCategoryIds = msgSendRuleManager.selectUsedCategoryIds(categoryIds);

        return sysCategoryConfigs.stream().map(cfg -> {
            SysCategoryConfigDetailVo vo = new SysCategoryConfigDetailVo();
            vo.setCategoryId(cfg.getId());
            vo.setCategoryName(cfg.getName());
            vo.setDeletable(!usedCategoryIds.contains(cfg.getId()));

            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 保存分类信息
     * <br />
     *
     * @param request
     * @return
     */
    @Override
    public int addConfig(SaveSysCategoryConfigReq request) {
        // 校验是否重名
        checkNameDuplicate(request.getCategoryId(), request.getCategoryName());

        // 保存分类
        Date nowTime = new Date();
        SysCategoryConfig entity = new SysCategoryConfig();
        entity.setBizType(request.getBizType());
        entity.setName(request.getCategoryName());
        entity.setCreateUserId(request.getOperatorUserId());
        entity.setUpdateUserId(request.getOperatorUserId());
        entity.setCreateTime(nowTime);
        entity.setUpdateTime(nowTime);
        categoryConfigManager.save(entity);
        return entity.getId();
    }

    /**
     * 修改分类信息
     * <br />
     *
     * @param categoryId
     * @param request
     * @return
     */
    @Override
    public int updateConfig(int categoryId, SaveSysCategoryConfigReq request) {
        SysCategoryConfig config = categoryConfigManager.getById(categoryId);
        if (config == null) {
            throw new BaseException("分类不存在");
        }

        checkNameDuplicate(request.getCategoryId(), request.getCategoryName());

        config.setName(request.getCategoryName());
        config.setUpdateUserId(request.getOperatorUserId());
        config.setUpdateTime(new Date());
        categoryConfigManager.updateById(config);
        return request.getCategoryId();
    }

    @Override
    public void deleteById(Integer categoryId) {
        Preconditions.checkArgument(categoryId != null, "分类ID不能为空");
        // 判断分类是否被弹窗规则使用
        List<Integer> usedCategoryIds = msgSendRuleManager.selectUsedCategoryIds(Collections.singletonList(categoryId));
        if (!usedCategoryIds.isEmpty()) {
            throw new BaseException("分类下存在弹窗规则，不能删除");
        }
        categoryConfigManager.removeById(categoryId);
    }

    /**
     * 新增、编辑分类时校验分类名称是否和其他分类重名
     * <br />
     * @param selfId 编辑时自己和自己重名不算（名字没修改），所以需要将自己排除
     * @param categoryName
     */
    private void checkNameDuplicate(Integer selfId, String categoryName) {
        LambdaQueryWrapper<SysCategoryConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(selfId != null, SysCategoryConfig::getId, selfId)
                .eq(SysCategoryConfig::getName, categoryName);

        if (categoryConfigManager.count(queryWrapper) > 0) {
            throw new BaseException("分类名称已存在");
        }
    }
}
